import axios from 'axios';
import { useStore } from 'src/pinia';
import {
    msgFn, showLoading, hideLoading, aesEncrypt, aesDecrypt, link
} from 'src/utils';
import { removePending, addPending } from 'src/plugins/http/cancelToken';
import env from 'src/config';

const {
    debuggerMode, appkey, isCrypto
} = env;
let loadingInstance = null,
    crypto = isCrypto;
// 添加请求拦截器
axios.interceptors.request.use(
    c => {
        const { user } = useStore();
        const config = { ...c };
        config.isLoading = config.isLoading ? config.isLoading : '1';
        if (Number(config.isLoading)) {
            showLoading(config.text ? { 'message': config.text } : {});
            loadingInstance = 1
        }
        crypto = config.headers.crypto ?? crypto;
        config.headers.crypto = crypto;
        config.headers.token = user.userInfo.token;
        config.headers.appkey = appkey;
        config.headers.secret = 'zlgb';
        const contentType = config.headers['Content-Type'];
        // eslint-disable-next-line no-undefined
        if ((contentType === undefined || contentType.indexOf('application/json') > -1) && Number(crypto)) {
            if (config.method === 'post') {
                config.data = { 'data': aesEncrypt(config.data) };
            }
            if (config.method === 'get') {
                config.params = { 'params': aesEncrypt(config.params) };
            }
        }
        removePending(config);
        addPending(axios, config);
        return config;
    },
    error => Promise.reject(error)
);

// 添加响应拦截器
axios.interceptors.response.use(
    response => {
        removePending(response);
        let { data, headers, request } = response;
        const contentType = headers['content-type'];
        const { code = 200 } = data;
        if (code === 200 && contentType.indexOf('application/json') > -1 && Number(crypto) && request.responseType !== 'blob') {
            data.data = aesDecrypt(response.data.data);
        }
        if (loadingInstance) { hideLoading(); }
        return response;
    },
    error => {
        if (loadingInstance) { hideLoading(); }
        Promise.resolve(error?.response);
    }
);

const httpServer = (options, d) => {
    const { user } = useStore();
    const Public = {};
    const opts = { ...options };
    // 公共参数
    opts.method = opts.method ? opts.method.toLowerCase().replace(/(^\s*)|(\s*$)/g, '') : 'post';
    const defaultOpts = {
        'method': 'post',
        'baseURL': '',
        'url': '',
        'timeout': 1000 * 60 * 2,
        'params': UtilTools.typeIs(d) === 'object' ? UtilTools.extend(Public, d) : d,
        'data': UtilTools.typeIs(d) === 'object' ? UtilTools.extend(Public, d) : d,
        'headers':
            opts.method === 'get' ?
                {
                    'X-Requested-With': 'XMLHttpRequest',
                    'Accept': 'application/json',
                    'Content-Type': 'application/json; charset=UTF-8'
                } :
                {
                    'Content-Type': 'application/json; charset=UTF-8'
                }
    };
    const httpDefaultOpts = UtilTools.extend(defaultOpts, opts);
    if (opts.method === 'get') {
        delete httpDefaultOpts.data;
    } else {
        delete httpDefaultOpts.params;
    }
    return new Promise((resolve, reject) => {
        let defaultErrMsg = 'internal server error',
            errCode = 500;
        axios(httpDefaultOpts)
            .then(res  => {
                const { data = {} } = res || {};
                const {
                    msg = defaultErrMsg, errMsg, code = errCode, returnCode = -1
                } = data;
                const sysCode = returnCode === 0 ? 200 : code;
                const sysMsg = errMsg || msg;
                if (sysCode >= 200 && sysCode < 400) {
                    resolve(data);
                } else if (sysCode === 401) {
                    msgFn(sysMsg);
                    reject(sysMsg);
                    if (!debuggerMode) {
                        // user.logout();
                        // setTimeout(() => {
                        //     link('/login');
                        // }, 2001);
                    }
                } else {
                    reject(sysMsg);
                }
            })
            .catch(error => {
                reject(error);
            });
    });
};

export default httpServer;
